home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Network Support Library
/
RoseWare - Network Support Library.iso
/
btrieve
/
sql_dp.arj
/
SIMRMI.PAS
next >
Wrap
Pascal/Delphi Source File
|
1993-08-08
|
6KB
|
186 lines
{Real mode interrupt support for protected mode using the DPMI.
Originally based on SIMRMI in C from the Microsoft DDK Dept.
Rex K. Perkins, CIS 70651,1611
6th March 1992.
Revised 10th December 1992}
Unit SimRMI;
Interface
Type
{Real Mode Register record for DPMI services. Variant type to allow
register reference by 32, 16 or 8 bit names. Fields ending in Low or
High are used for padding only and are not intended for use. [Anyone
know a better way?]
This arangement allows the direct reference of the following registers:
8 bit: AL, AH, BL, BH, CL,CH, DL, DH
16 bit: AX, BX, CX, DX, BP, SI, DI, Flags, ES, DS, FS, GS, IP, CS, SP, SS
32 bit: EAX, EBX, ECX, EDX, EDI, ESI, EBP}
PRealModeRecord=^TRealModeRecord;
TRealModeRecord=
Record
Case Byte Of
0: {32 bit registers}
(EDI,ESI,EBP,Reserved,EBX,EDX,
ECX,EAX:LongInt);
1: {16 bit registers}
(DI,DIHigh,SI,SIHigh,
BP,BPHigh,ReservedLow,ReservedHigh,
BX,BXHigh,DX,DXHigh,
CX,CXHigh,AX,AXHigh,
Flags,ES,DS,FS,GS,IP,
CS,SP,SS:Word);
2: {8 bit registers}
(DILowLow,DILowHigh,DIHighLow,DIHighHigh,
SILowLow,SILowHigh,SIHighLow,SIHighHigh,
BPLowLow,BPLowHigh,BPHighLow,BPHighHigh,
ReservedLowLow,ReservedLowHigh,ReservedHighLow,ReservedHighHigh,
BL,BH,BXHighLow,BXHighHigh,
DL,DH,DXHighLow,DXHighHigh,
CL,CH,CXHighLow,CXHighHigh,
AL,AH,AXHighLow,AXHighHigh:Byte)
End;
Const
{Pass this constant if you don't need to clear all undefined registers.
Ensures all selector / segment registers are valid}
DefaultRMR:TRealModeRecord=(
EDI:0;
ESI:0;
EBP:0;
Reserved:0;
EBX:0;
EDX:0;
ECX:0;
EAX:0;
Flags:0;
ES:0;
DS:0;
FS:0;
GS:0;
IP:0;
CS:0;
SP:0;
SS:0);
Function SimRealModeInt(IntNumber:Byte; RealModeRegisters:PRealModeRecord):Boolean;
{Simulate a call to the spectified real mode interrupt. The registers passed
to the real mode code are held in RealModeRegisters. This structure contains
the register content upon termination of the real mode ISR.
Returns False if there was an error.}
Function CheckISRInstalled(IntVec:Byte):Boolean;
{Check that there is an Interrupt Service Routine installed. Returns true if a non-zero segment
was found in the specified ISR vector. If returns False, there is not a valid
address in the interrupt vector so the interrupt should not be called}
Function GetISRAddress(IntVec:Byte):Pointer;
{Returns the REAL MODE ISR address for vector IntVec. Note that this
pointer is in Segment:Offset format, not Selector:Offset}
Implementation
Function SimRealModeInt(IntNumber:Byte; RealModeRegisters:PRealModeRecord):Boolean; Assembler;
{Simulate a call to the spectified real mode interrupt. The registers passed
to the real mode code are held in RealModeRegisters. This structure contains
the register content upon termination of the real mode ISR.
Returns False if there was an error.}
ASM
push di
push es
mov bh,00 {For DOSX to reset the int controller and A20 line. Windows ingores it.}
mov bl,IntNumber {Tell DPMI which interrupt to simulate}
xor cx,cx {0 bytes to copy to real mode stack}
les di,RealModeRegisters{Get the real mode structure}
mov ax,$0300 {Function 0300h is simulate real mode interrupt}
int 31h
jc @Error {The carry flag was set, so there was an error}
mov ax,True {Return no error}
jmp @AllDone
@Error:
mov ax,False {Return false indicating an error}
@AllDone:
pop es
pop di
End;
Function CheckISRInstalled(IntVec:Byte):Boolean;
{Check that there is an ISR installed. Returns true if a non-zero segment
was found in the specified ISR vector. If returns False, there is not a valid
address in the interrupt vector so the interrupt should not be called}
Var ISRSegment:Word;
Begin
ASM
mov ax,0200h {DPMI Get Real Mode Interrupt Vector}
mov bl,IntVec {Check for the specified interrupt}
int 31h {Call DPMI}
mov ISRSegment,cx {CX holds the ISR segment}
End;
If ISRSegment<>0 Then {The Int vector is not 0 so there must be an ISR}
CheckISRInstalled:=True
Else
CheckISRInstalled:=False
End;
Function GetISRAddress(IntVec:Byte):Pointer;
{Returns the REAL MODE ISR address for vector IntVec. Note that this
pointer is in Segment:Offset format, not Selector:Offset}
Var ISRSegment,ISROffset:Word;
Begin
ASM
mov ax,0200h {DPMI Get Real Mode Interrupt Vector}
mov bl,IntVec {Check for the specified interrupt}
int 31h {Call DPMI}
mov ISRSegment,cx {CX holds the ISR segment}
mov ISROffset,ds {DX holds the ISR offset}
End;
GetISRAddress:=PTR(ISRSegment,ISROffset) {Return the pointer}
End;
Begin
End.